#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
重试处理器

该模块提供了HTTP请求重试的处理器，支持自定义重试策略。

创建时间: 2023-07-15
作者: Python Tools Team
"""

from typing import List, Union, Optional, Set


class RetryHandler:
    """
    重试处理器类
    
    提供了HTTP请求重试的配置和策略。
    """
    
    def __init__(self, 
                 max_retries: int = 3, 
                 backoff_factor: float = 0.3,
                 status_codes: Optional[List[int]] = None,
                 methods: Optional[List[str]] = None):
        """
        初始化重试处理器
        
        Args:
            max_retries: 最大重试次数
            backoff_factor: 退避因子，用于计算重试间隔
                           重试间隔 = {backoff_factor} * (2 ** ({重试次数} - 1))
            status_codes: 触发重试的HTTP状态码列表
            methods: 允许重试的HTTP方法列表
        """
        self.max_retries = max_retries
        self.backoff_factor = backoff_factor
        self.status_codes = status_codes or [429, 500, 502, 503, 504]
        self.methods = methods or ['GET', 'HEAD', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']
    
    @classmethod
    def default(cls) -> 'RetryHandler':
        """
        创建默认的重试处理器
        
        Returns:
            RetryHandler: 默认配置的重试处理器
        """
        return cls()
    
    @classmethod
    def aggressive(cls) -> 'RetryHandler':
        """
        创建激进的重试处理器，适用于不稳定的网络环境
        
        Returns:
            RetryHandler: 配置为激进重试策略的处理器
        """
        return cls(
            max_retries=5,
            backoff_factor=0.5,
            status_codes=[429, 500, 502, 503, 504, 408, 520, 521, 522, 523, 524],
            methods=['GET', 'HEAD', 'PUT', 'DELETE', 'OPTIONS', 'TRACE', 'POST', 'PATCH']
        )
    
    @classmethod
    def conservative(cls) -> 'RetryHandler':
        """
        创建保守的重试处理器，仅对幂等方法和服务器错误重试
        
        Returns:
            RetryHandler: 配置为保守重试策略的处理器
        """
        return cls(
            max_retries=2,
            backoff_factor=0.2,
            status_codes=[500, 502, 503, 504],
            methods=['GET', 'HEAD', 'OPTIONS']
        )
    
    def with_max_retries(self, max_retries: int) -> 'RetryHandler':
        """
        设置最大重试次数
        
        Args:
            max_retries: 最大重试次数
            
        Returns:
            RetryHandler: 当前处理器实例（用于链式调用）
        """
        self.max_retries = max_retries
        return self
    
    def with_backoff_factor(self, backoff_factor: float) -> 'RetryHandler':
        """
        设置退避因子
        
        Args:
            backoff_factor: 退避因子
            
        Returns:
            RetryHandler: 当前处理器实例（用于链式调用）
        """
        self.backoff_factor = backoff_factor
        return self
    
    def with_status_codes(self, status_codes: List[int]) -> 'RetryHandler':
        """
        设置触发重试的HTTP状态码列表
        
        Args:
            status_codes: 状态码列表
            
        Returns:
            RetryHandler: 当前处理器实例（用于链式调用）
        """
        self.status_codes = status_codes
        return self
    
    def with_methods(self, methods: List[str]) -> 'RetryHandler':
        """
        设置允许重试的HTTP方法列表
        
        Args:
            methods: 方法列表
            
        Returns:
            RetryHandler: 当前处理器实例（用于链式调用）
        """
        self.methods = methods
        return self
    
    def add_status_code(self, status_code: int) -> 'RetryHandler':
        """
        添加触发重试的HTTP状态码
        
        Args:
            status_code: 状态码
            
        Returns:
            RetryHandler: 当前处理器实例（用于链式调用）
        """
        if status_code not in self.status_codes:
            self.status_codes.append(status_code)
        return self
    
    def add_method(self, method: str) -> 'RetryHandler':
        """
        添加允许重试的HTTP方法
        
        Args:
            method: 方法名
            
        Returns:
            RetryHandler: 当前处理器实例（用于链式调用）
        """
        method = method.upper()
        if method not in self.methods:
            self.methods.append(method)
        return self